﻿import sys
import numpy as np  
import cv2
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QFileDialog, QPushButton,QWidget, QVBoxLayout, QHBoxLayout, QInputDialog,QSlider,QLineEdit
from PyQt5.QtGui import QPixmap, QImage,QTransform,QFont
from PyQt5.QtCore import Qt,pyqtSlot 
from PIL import Image, ImageEnhance
from ultralytics import YOLO
# 0
class ImageProcessingApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.pil_image = None# 添加实例变量来存储 PIL 图像

    def initUI(self):
                
         # 创建一个横布局
        layout = QHBoxLayout()
        self.setWindowTitle('图像处理应用')
        self.setFixedSize(1500, 800) 
        # self.setGeometry(100, 100, 800, 600)
        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        buttonLayout = QVBoxLayout()
        imageLayout =QVBoxLayout()
        imageLayout2 =QHBoxLayout()
        buttonLayout2 = QVBoxLayout()
        
        # 将垂直布局添加到水平布局中
        layout.addLayout(buttonLayout)
        layout.addLayout(imageLayout)
        layout.addLayout(buttonLayout2)
        imageLayout.addLayout(imageLayout2)
        
         # 创建一个 QLineEdit 对象  
#         self.gaussianBlurInput = QLabel(self)  
# #  如果需要，设置一些属性，比如提示文本  
#         self.gaussianBlurInput.setText("老虎姿势识别系统")  
# # 设置固定宽度（如果需要）  
#         self.gaussianBlurInput.setFixedWidth(600)
#         # 创建一个 QFont 对象并设置字体大小  
#         font = QFont()  
#         font.setPointSize(30)  # 设置字体大小为 20 点  
#         self.gaussianBlurInput.setAlignment(Qt.AlignCenter)
  
# # 将 QFont 对象应用到 QLabel 上  
#         self.gaussianBlurInput.setFont(font)  
  
# # 将 QLineEdit 添加到布局中  
#         imageLayout.addWidget(self.gaussianBlurInput)  
        
        
        
         # 创建一个 QLineEdit 对象  
        self.gaussianBlurOUTput = QLabel(self)  
#  如果需要，设置一些属性，比如提示文本  
        self.gaussianBlurOUTput.setText("正在识别中")  
# 设置固定宽度（如果需要）  
        self.gaussianBlurOUTput.setFixedWidth(600)
        # 创建一个 QFont 对象并设置字体大小  
        font1 = QFont()  
        font1.setPointSize(8) 
        self.gaussianBlurOUTput.setAlignment(Qt.AlignCenter) 
  
# 将 QFont 对象应用到 QLabel 上  
        self.gaussianBlurOUTput.setFont(font1)  
  
# 将 QLineEdit 添加到布局中  
        imageLayout.addWidget(self.gaussianBlurOUTput)  

        
        self.imageLabel = QLabel(self)
        self.imageLabel.setAlignment(Qt.AlignCenter)
        self.processedImageLabel = QLabel(self)
        self.processedImageLabel.setAlignment(Qt.AlignCenter)
        # self.imageLabel.setGeometry(10, 10, 780, 580)
        imageLayout2.addWidget(self.imageLabel)
        imageLayout2.addWidget(self.processedImageLabel)
        self.scale_factor = 1.0 
        # imageLayout.addWidget(self.imageLabel)

        # 创建一个按钮来打开文件对话框
        self.openButton = QPushButton('打开图像', self)
        self.openButton.clicked.connect(self.openImage)
        # self.openButton.move(10, 10)
        # self.openButton.setGeometry(10, 10, 100, 30) 
        buttonLayout.addWidget(self.openButton)
        
        self.openButton.setStyleSheet('''
            QPushButton{
                background:#CCFFFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.openButton.setFixedWidth(100)

        self.grayscaleButton = QPushButton('灰度化', self)
        self.grayscaleButton.clicked.connect(self.toGrayscale)
        # self.grayscaleButton.move(10, 50)
        buttonLayout2.addWidget(self.grayscaleButton)
        
        self.grayscaleButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.grayscaleButton.setFixedWidth(100)
         # 创建一个按钮来调节对比度
        self.contrastButton = QPushButton('对比度调节', self)  
        self.contrastButton.clicked.connect(self.adjust_contrast)  
        # self.contrastButton.move(10, 90) 
        buttonLayout.addWidget(self.contrastButton)
        
        self.contrastButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.contrastButton.setFixedWidth(100)
        
        
          # 创建一个按钮来调节亮度  
        self.brightnessButton = QPushButton('亮度调节', self)  
        self.brightnessButton.clicked.connect(self.adjustBrightness)  
        buttonLayout.addWidget(self.brightnessButton)
        # self.brightnessButton.setGeometry(120, 10, 100, 30)  
        # self.brightnessButton.setGeometry(120, 10, 100, 30) 
        
        self.brightnessButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.brightnessButton.setFixedWidth(100)
        
        
        self.lightsenseButton = QPushButton('光感调节', self)  
        self.lightsenseButton.clicked.connect(self.adjustLightSense)  # 连接光感调节按钮到方法  
        # self.lightsenseButton.setGeometry(120, 90, 100, 30)
        buttonLayout.addWidget(self.lightsenseButton)
        
        self.lightsenseButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.lightsenseButton.setFixedWidth(100)
        
        
          # 创建一个按钮来直方图均衡化  
        self.equalizeHistogramButton = QPushButton('直方图均衡化', self)  
        self.equalizeHistogramButton.clicked.connect(self.equalizeHistogram)  
        buttonLayout2.addWidget(self.equalizeHistogramButton)
        
        self.equalizeHistogramButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.equalizeHistogramButton.setFixedWidth(100)

        
          # 创建一个按钮来锐化处理  
        self.crispButton = QPushButton('锐化处理', self)  
        self.crispButton.clicked.connect(self.crispEnhancement)  
        buttonLayout2.addWidget(self.crispButton)
        
        self.crispButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.crispButton.setFixedWidth(100)


          # 创建一个按钮来高斯模糊  
        self.gaussianBlurredButton = QPushButton('高斯模糊', self)  
        self.gaussianBlurredButton.clicked.connect(self.gaussianBlurred)  
        buttonLayout2.addWidget(self.gaussianBlurredButton)
        
        self.gaussianBlurredButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.gaussianBlurredButton.setFixedWidth(100)
        
       

          # 创建一个按钮来中值模糊 
        self.medianBlurredButton = QPushButton('中值模糊', self)  
        self.medianBlurredButton.clicked.connect(self.medianBlurred)  
        buttonLayout2.addWidget(self.medianBlurredButton)
        
        self.medianBlurredButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.medianBlurredButton.setFixedWidth(100)

          # 创建一个按钮来双边滤波 
        self.bilateralBlurredButton = QPushButton('双边滤波', self)  
        self.bilateralBlurredButton.clicked.connect(self.bilateralBlurred)  
        buttonLayout2.addWidget(self.bilateralBlurredButton)
        
        self.bilateralBlurredButton.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.bilateralBlurredButton.setFixedWidth(100)

         # 创建一个按钮来平移图像  
        self.translate_button = QPushButton('平移图像', self)  
        self.translate_button.clicked.connect(self.translate_image)  
        buttonLayout2.addWidget(self.translate_button)  
        self.translate_button.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.translate_button.setFixedWidth(100)

        # 创建一个按钮来旋转图像 
        self.rotate_button = QPushButton('旋转图像', self)  
        self.rotate_button.clicked.connect(self.rotate_image)
        buttonLayout.addWidget(self.rotate_button)
        
        self.rotate_button.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.rotate_button.setFixedWidth(100)
 
        # 创建按钮用于缩放图像
        self.scale_button = QPushButton('缩放图像', self)  
        self.scale_button.clicked.connect(self.scaleImageByButton) 
        buttonLayout2.addWidget(self.scale_button) 
        
        self.scale_button.setStyleSheet('''
            QPushButton{
                background:#FFCCFF;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.scale_button.setFixedWidth(100)

        # # 创建HSL调节的滑块
        self.createHSLSliders(buttonLayout)
        # 创建姿势识别的按钮
        self.pose_button = QPushButton('姿势识别', self)  
        self.pose_button.clicked.connect(self.poseButton) 
        buttonLayout2.addWidget(self.pose_button) 
        
        self.pose_button.setStyleSheet('''
            QPushButton{
                background:#CCFFCC;
                border-radius:5px;}
            QPushButton:hover{
                background:grey;}''')
        self.pose_button.setFixedWidth(100)

        layout.addLayout(buttonLayout)
        layout.addWidget(self.imageLabel)
        layout.addWidget(self.processedImageLabel)

          # 设置主窗口的布局
        # container = QWidget()
        # container.setLayout(layout)
        # self.setCentralWidget(container)
        # layout.addWidget(self.imageLabel)
        # self.setCentralWidget(self.imageLabel) 

    def openImage(self):
        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getOpenFileName(self,"打开图像","","所有图像文件 (*);;PNG 文件 (*.png);;JPEG 文件 (*.jpeg);;JPG 文件 (*.jpg)", options=options)
        if fileName:
           # 使用 PIL 的 Image.open 打开图像
            #pil_image = Image.open(fileName)
            # 使用 PIL 的 Image.open 打开图像  
            self.pil_image = Image.open(fileName) 
            # 获取Exif信息
            exif = self.pil_image._getexif()
            
            # 如果存在Exif信息，尝试获取Orientation标签
            if exif is not None:
                print(exif)
                # Exif Orientation标签
                orientation_tag = 274
                
                # 获取Orientation值
                orientation = exif.get(orientation_tag, 1)
                
                # 根据Orientation值旋转图片
                rotations = {
                    3: Image.ROTATE_180,
                    6: Image.ROTATE_270,
                    8: Image.ROTATE_90,
                }
                if orientation in rotations:
                    self.pil_image = self.pil_image.transpose(rotations[orientation])
            
            # 将 PIL 图像转换为 PyQt 的 QImage
            # 首先确保图像是 RGB 格式
            #pil_image = pil_image.convert('RGB')
            self.pil_image = self.pil_image.convert('RGB')
            # self.showImage()  
            # print(self.pil_image)
            # 获取图像的宽度和高度
            width, height = self.pil_image.size
#             new_width = 800  
#             new_height = 600  
  
# # 使用 Image.resize() 方法调整图像大小  
#             resized_image = self.pil_image.resize((new_width, new_height)) 

            mode = self.pil_image.mode

            # 计算每个像素的字节数
            # 'L' (灰度) 模式每个像素1字节, 'RGB' 模式每个像素3字节, 'RGBA' 模式每个像素4字节等
            pixel_bytes = len(mode)

            # 计算每行的字节数
            self.row_bytes = width * pixel_bytes

            qimage = QImage(self.pil_image.tobytes(),  
                           self.pil_image.size[0],  
                           self.pil_image.size[1],  self.row_bytes,
                           QImage.Format_RGB888)
            #qimage = QImage(pil_image.tobytes(), pil_image.size[0], pil_image.size[1], QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(qimage)
            self.current_pixmap = pixmap
           # self.imageLabel.setPixmap(pixmap)
            self.imageLabel.setPixmap(pixmap.scaled(300, 300, Qt.KeepAspectRatio))  # 你可以根据需要调整大小
           # imageLayout.addWidget(self.imageLabel) 
            
   
    def toGrayscale(self):
        if self.imageLabel.pixmap():
            # 获取当前显示的 QPixmap
            pixmap = self.imageLabel.pixmap()
            # 将 QPixmap 转换为 QImage
            image = pixmap.toImage()
            # 将 QImage 转换为灰度格式
            image = image.convertToFormat(QImage.Format_Grayscale8)
            # 创建一个新的 QPixmap 来显示灰度图像
            pixmap = QPixmap.fromImage(image)
            #self.processedImageLabel.setPixmap(pixmap)
            self.processedImageLabel.setPixmap(pixmap.scaled(300, 300, Qt.KeepAspectRatio))  # 你可以根据需要调整大小
    def showImage(self):  
        # 将 PIL 图像转换为 QImage  
        qimage = QImage(self.pil_image.tobytes(),  
                         self.pil_image.size[0], self.pil_image.size[1],  self.row_bytes,
                         QImage.Format_RGB888)  
        pixmap = QPixmap.fromImage(qimage)  
        #self.processedImageLabel.setPixmap(pixmap) 
        self.processedImageLabel.setPixmap(pixmap.scaled(300, 300, Qt.KeepAspectRatio)) 
        
#光感
        
    def adjustLightSense(self):  
        a, ok = QInputDialog.getInt(self, "光感调节", "请输入光感调节强度 (0-100):")  
        if ok:  
            # 检查输入是否在有效范围内  
            a = max(0, min(a, 100))  
            self.lightSense(a) 
  
    def lightSense(self, a):  
        # 确保 PIL 图像存在  
        if self.pil_image is None:  
            return  
  
        # 将 PIL 图像转换为 numpy 数组  
        img_np = np.array(self.pil_image)  
  
        # 计算光感调节值  
        a_val = np.float32(a - 50) / 50.0  # 将0~100映射到-1~1  
  
        # 应用光感调节  
        res_np = img_np.astype(np.float32)  
        res_np += a_val * res_np  
        res_np = np.clip(res_np, 0, 255)  # 确保值在0~255范围内  
        res_np = res_np.astype(np.uint8)  
  
        # 将 numpy 数组转回 PIL 图像  
        self.pil_image = Image.fromarray(res_np)  
  
        # 更新标签显示新图像  
        self.showImage()
    
  
    def adjustBrightness(self):  
        # 弹出对话框获取亮度值  
        brightness, ok = QInputDialog.getInt(self, '亮度调节', '请输入亮度值 (0-100):')  
        if ok and 0 <= brightness <= 100:  
            self.pil_image = self.adjust_brightness(self.pil_image, brightness)  
            self.showImage()  
  
    def adjust_brightness(self, image, brightness):  
        # 将 PIL 图像转换为 NumPy 数组  
        array = np.array(image)  
  
        # 将亮度值转换为调整因子  
        brightness_factor = (brightness - 50) / 100.0  
  
        # 调整亮度  
        array = array.astype(np.float32)  
        array += brightness_factor * 255  
        array = np.clip(array, 0, 255).astype(np.uint8)  
  
        # 将 NumPy 数组转换回 PIL 图像  
        return Image.fromarray(array)  
 # 调节对比度  
    def adjust_contrast(self):  
        if self.pil_image is None:  
            print("请先加载图像")  
            return  
  
        # 将 PIL 图像转换为 NumPy 数组  
        np_image = np.array(self. pil_image)  
  
        # 这里我们假设用户通过一个对话框或其他方式输入对比度因子  
        # 为了简单起见，这里我们硬编码一个值  
        contrast_factor = 1.5  # 示例值，您可以根据需要更改或添加输入对话框  
  
        # 应用对比度调整  
        contrast_factor = np.float32(contrast_factor)  
        table = np.array([(i - 128) * contrast_factor + 128 for i in range(0, 256)]).clip(0, 255).astype(np.uint8)  
  
        # 应用查找表到每个颜色通道  
        adjusted_image = cv2.LUT(np_image, table)  
  
        # 将 NumPy 数组转换回 PIL 图像  
        pil_adjusted_image = Image.fromarray(cv2.cvtColor(adjusted_image, cv2.COLOR_BGR2RGB))  
  
        # 将 PIL 图像转换为 QImage 并显示在标签上  
        qimage = QImage(pil_adjusted_image.tobytes(),  
                         pil_adjusted_image.size[0],  
                         pil_adjusted_image.size[1],  self.row_bytes,
                         QImage.Format_RGB888)  
        pixmap = QPixmap.fromImage(qimage)  
        #self.processedImageLabel.setPixmap(pixmap)
        self.processedImageLabel.setPixmap(pixmap.scaled(300, 300, Qt.KeepAspectRatio))

    def equalizeHistogram(self):
        # 直方图均衡化
        if self.imageLabel.pixmap():
            img_np = np.array(self.pil_image)
            # 如果图像是彩色的，转换为灰度图
            if len(img_np.shape) > 2:
                img_np = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)

            # 执行直方图均衡化
            equalized_img = cv2.equalizeHist(img_np)

            # 将均衡化后的图像转换回PIL格式，以便在GUI中显示
            # equalized_pil_img = Image.fromarray(equalized_img)
        
            # 获取当前显示的 QPixmap
            # pixmap = self.imageLabel.pixmap()
            #  # 将 QPixmap 转换为 OpenCV 格式的图像
            # image = pixmap.toImage()
            # width, height = image.width(), image.height()
            # bytesPerLine = image.bytesPerLine()
            # cv_image = np.frombuffer(image.bits().asstring(width * height * 4), dtype=np.uint8).reshape((height, width, 4))
            # cv_image = cv2.cvtColor(cv_image, cv2.COLOR_RGBA2BGR)
            # # 将彩色图像转换为灰度图像
            # gray_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)
            # # 直方图均衡化
            # equalized_image = cv2.equalizeHist(gray_image)

            # # 将处理后的图像转换回 QImage 和 QPixmap
            # equalized_image = cv2.cvtColor(equalized_image, cv2.COLOR_BGR2RGBA)
            # qimage = QImage(equalized_image.data, equalized_image.shape[1], equalized_image.shape[0],self.row_bytes, QImage.Format_RGBA8888)
            # qpixmap = QPixmap.fromImage(qimage)
            # self.showNpImg(qpixmap)
            # 将PIL图像转换为QImage
            equalized_qimage = QImage(equalized_img.data, equalized_img.shape[1], equalized_img.shape[0],img_np.strides[0], QImage.Format_Grayscale8)

            # 将QImage转换为QPixmap
            equalized_qpixmap = QPixmap.fromImage(equalized_qimage)
            #self.processedImageLabel.setPixmap(equalized_qpixmap)
            self.processedImageLabel.setPixmap(equalized_qpixmap.scaled(300, 300, Qt.KeepAspectRatio))
            
    def createHSLSliders(self, layout):
        # 创建水平布局
        h_layout = QVBoxLayout()

        # 创建色相滑块
        self.hueSlider = QSlider(Qt.Horizontal)
        self.hueSlider.setMinimum(-180)
        self.hueSlider.setMaximum(180)
        self.hueSlider.setValue(0)
        self.hueSlider.valueChanged.connect(self.adjustHSL)
        h_layout.addWidget(self.hueSlider)
        self.hueSlider.setFixedWidth(100)

        # 创建饱和度滑块
        self.saturationSlider = QSlider(Qt.Horizontal)
        self.saturationSlider.setMinimum(-255)
        self.saturationSlider.setMaximum(255)
        self.saturationSlider.setValue(0)
        self.saturationSlider.valueChanged.connect(self.adjustHSL)
        h_layout.addWidget(self.saturationSlider)
        self.saturationSlider.setFixedWidth(100)

        # 创建亮度滑块
        self.lightnessSlider = QSlider(Qt.Horizontal)
        self.lightnessSlider.setMinimum(-255)
        self.lightnessSlider.setMaximum(255)
        self.lightnessSlider.setValue(0)
        self.lightnessSlider.valueChanged.connect(self.adjustHSL)
        h_layout.addWidget(self.lightnessSlider)
        self.lightnessSlider.setFixedWidth(100)

        # 创建滑块用于调整缩放级别（可选）  
       # self.slider = QSlider(Qt.Horizontal, self)  
       # self.slider.setMinimum(10)  
       # self.slider.setMaximum(300)  
       # self.slider.setValue(100)  
       # self.slider.valueChanged.connect(self.scaleImageBySlider) 

        # 添加水平布局到主布局
        layout.addLayout(h_layout)
        # # layout.addStretch()
        # h_layout.setGeometry(100, 500, 200, 100)
         # 创建一个容器来放置HSL布局
        # hsl_container = QWidget()
        # hsl_container.setLayout(h_layout)

        # # 设置HSL布局的位置和大小
        # hsl_container.setGeometry(100, 500, 200, 100)

        # # 将HSL布局添加到主布局中
        # layout.addWidget(h_layout)
    
    

    def adjustHSL(self):
        # 获取滑块值
        if self.imageLabel.pixmap():
            hue = self.hueSlider.value()
            saturation = self.saturationSlider.value() 
            lightness = self.lightnessSlider.value()
            img_np = np.array(self.pil_image)  
            hsv_image = cv2.cvtColor(img_np, cv2.COLOR_BGR2HSV)
            hsv_adjusted = np.zeros_like(hsv_image)

            # 对HSV图像的每个通道分别进行调整
            hsv_adjusted[:, :, 0] = cv2.add(hsv_image[:, :, 0], hue)  # 色相调整
            hsv_adjusted[:, :, 1] = cv2.add(hsv_image[:, :, 1], saturation)  # 饱和度调整
            hsv_adjusted[:, :, 2] = cv2.add(hsv_image[:, :, 2], lightness)  # 亮度调整

            # 将调整后的HSV图像转换回BGR图像
            adjusted_image = cv2.cvtColor(hsv_adjusted, cv2.COLOR_HSV2BGR)
            # img = convertToHSL(img_np)
            # dst = HSL(img,hue,saturation,lightness)
            # dst = convertToBGR(dst)
            # self.pil_image = Image.fromarray(adjusted_image)  
            qimage = QImage(adjusted_image.data, adjusted_image.shape[1], adjusted_image.shape[0],self.row_bytes, QImage.Format_RGB888)

            # 使用 QImage 创建 QPixmap
            qpixmap = QPixmap.fromImage(qimage)
            # 更新标签显示新图像  
            #self.processedImageLabel.setPixmap(qpixmap) 
            self.processedImageLabel.setPixmap(qpixmap.scaled(300, 300, Qt.KeepAspectRatio))
            
    def crispEnhancement(self):
        if self.imageLabel.pixmap():
            # 将PIL图像转换为numpy数组
            img_np = np.array(self.pil_image)  

            # 将图像转换为OpenCV的BGR格式
            bgr_image = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)

            # 使用Laplacian算子进行锐化
            lap = cv2.Laplacian(bgr_image, cv2.CV_64F)

            # 将Laplacian结果转换回8位整数
            lap = cv2.convertScaleAbs(lap)

            # 将锐化后的图像与原始图像相加，得到最终结果
            sharpened = cv2.addWeighted(bgr_image, 1.0, lap, 0.5, 0)

            # 将锐化后的BGR图像转换回RGB格式
            sharpened_rgb = cv2.cvtColor(sharpened, cv2.COLOR_BGR2RGB)

            # 创建 QImage
            qimage = QImage(sharpened_rgb.data, sharpened_rgb.shape[1], sharpened_rgb.shape[0],self.row_bytes, QImage.Format_RGB888)

            # 使用 QImage 创建 QPixmap
            qpixmap = QPixmap.fromImage(qimage)
            # 更新标签显示新图像  
            #self.processedImageLabel.setPixmap(qpixmap) 
            self.processedImageLabel.setPixmap(qpixmap.scaled(300, 300, Qt.KeepAspectRatio))
    def gaussianBlurred(self):
        if self.imageLabel.pixmap():
            # 将PIL图像转换为numpy数组
            img_np = np.array(self.pil_image)
            gaussian_blurred = cv2.GaussianBlur(img_np, (5, 5), 0)  
            self.showNpImg(gaussian_blurred)
    def medianBlurred(self):
        if self.imageLabel.pixmap():
            # 将PIL图像转换为numpy数组
            img_np = np.array(self.pil_image)
            gaussian_blurred = cv2.medianBlur(img_np, 5) 
            self.showNpImg(gaussian_blurred)
    def bilateralBlurred(self):
        if self.imageLabel.pixmap():
            # 将PIL图像转换为numpy数组
            img_np = np.array(self.pil_image)
            gaussian_blurred = cv2.bilateralFilter(img_np, 9, 75, 75)
            self.showNpImg(gaussian_blurred)
    def translate_image(self):  
        # 设置平移量  
        tx, ty = 10, 20  
        # 创建平移矩阵  
        M = np.float32([[1, 0, tx], [0, 1, ty]])  
        # 应用仿射变换（平移）  
        opencv_image = cv2.cvtColor(np.array(self.pil_image), cv2.COLOR_RGB2BGR) 
        translated_image = cv2.warpAffine(opencv_image, M, (opencv_image.shape[1], opencv_image.shape[0]))  
        translated_image_rgb = cv2.cvtColor(translated_image, cv2.COLOR_BGR2RGB)
        # 转换OpenCV图像为QImage以在QLabel中显示  
        h, w, ch = translated_image_rgb.shape  
        bytesPerLine = ch * w  
        convertToQtFormat = QImage(translated_image_rgb.data, w, h, bytesPerLine, QImage.Format_RGB888)  
        self.pixmap = QPixmap.fromImage(convertToQtFormat)  
        # 显示平移后的图像，保持原始比例  
        self.processedImageLabel.setPixmap(self.pixmap.scaled(self.imageLabel.size(), Qt.KeepAspectRatio))

    def rotate_image(self):  
        # 获取当前的图像  
        pixmap = self.imageLabel.pixmap()  
  
        # 创建一个变换对象并设置旋转角度（这里我们每次旋转90度）  
        transform = QTransform().rotate(90)  
  
        # 应用变换并更新标签的图像  
        transformed_pixmap = pixmap.transformed(transform, Qt.SmoothTransformation)  
        #self.processedImageLabel.setPixmap(transformed_pixmap) 
        self.processedImageLabel.setPixmap(transformed_pixmap.scaled(300, 300, Qt.KeepAspectRatio))

    def scaleImageBySlider(self, value):  
        # 根据滑块的值计算缩放因子并缩放图像  
        self.scale_factor = value / 100.0  
        scaled_pixmap = self.pixmap.scaled(  
            int(self.pixmap.width() * self.scale_factor),  
            int(self.pixmap.height() * self.scale_factor),  
            Qt.KeepAspectRatio  
        )  
        #self.processedImageLabel.setPixmap(scaled_pixmap)  
        self.processedImageLabel.setPixmap(scaled_pixmap.scaled(300, 300, Qt.KeepAspectRatio))
        # self.current_pixmap = scaled_pixmap  
  
    def scaleImageByButton(self):  
        # 通过按钮点击来缩放图像（例如，放大或缩小一定比例）  
        new_scale_factor = self.scale_factor * 0.5  # 放大1.2倍，您可以根据需要调整这个值  
        scaled_pixmap = self.imageLabel.pixmap().scaled(  
            int(self.imageLabel.pixmap().width() * new_scale_factor),  
            int(self.imageLabel.pixmap().height() * new_scale_factor),  
            Qt.KeepAspectRatio  
        )  
        #self.processedImageLabel.setPixmap(scaled_pixmap)  
        self.processedImageLabel.setPixmap(scaled_pixmap.scaled(300, 300, Qt.KeepAspectRatio))
        # self.current_pixmap = scaled_pixmap  
        self.scale_factor = new_scale_factor

    def showNpImg(self,img):
             # 创建 QImage
            qimage = QImage(img.data, img.shape[1], img.shape[0], self.row_bytes,QImage.Format_RGB888)

            # 使用 QImage 创建 QPixmap
            qpixmap = QPixmap.fromImage(qimage)
            # 更新标签显示新图像  
            #self.processedImageLabel.setPixmap(qpixmap) 
            self.processedImageLabel.setPixmap(qpixmap.scaled(300, 300, Qt.KeepAspectRatio))

    def poseButton(self):
        # Load a model
        model = YOLO('yolov8x-pose.pt')  # load an official model
        # model = YOLO(r'runs\pose\tiger-pose\train2\weights\best.pt')  # load a custom model
        model = YOLO(r'runs\pose\x_2\train6\weights\best.pt')  # load a custom model
        # model = YOLO(r'runs\pose\x_1\train3\weights\best.pt')  # load a custom model

        # Predict with the model
        # results = model(r'data\pose4\val\images\000049.jpg' )  # predict on an image
        colors = [[255, 128, 0], [255, 153, 51], [255, 178, 102], [230, 230, 0], [255, 153, 255],
                                              [153, 204, 255], [255, 102, 255], [255, 51, 255], [102, 178, 255], [51, 153, 255],
                                              [255, 153, 153], [255, 102, 102], [255, 51, 51], [153, 255, 153], [102, 255, 102],
                                              [51, 255, 51], [0, 255, 0], [0, 0, 255], [255, 0, 0], [255, 255, 255]]
        img = np.array(self.pil_image)
        results = model(img)  # predict on an image
        # img = cv2.imread(img_np)
        # results = model(r'data\pose4\train\images\000172.jpg' )  # predict on an image
        # img = cv2.imread(r'data\pose4\train\images\000172.jpg')
        for result in results:
            keypoints = result.keypoints
            h, w = keypoints.orig_shape
            xyn = keypoints.xyn[0]
            kpts = []

            for i in range(len(xyn)):
                x = xyn[i][0].item() * w
                y = xyn[i][1].item()* h
               
                cv2.circle(img,(int(x),int(y)),1,colors[i],2)
                kpts.append([int(x),int(y)])
            kpt_line = [[0, 2], [1, 2], [2, 14], [5, 6], [5, 14], [3, 4], [3, 14], [13, 14], [9, 8], [8, 7], [7, 13], [12, 11], [11, 10], [10, 13]]
            for j in range(len(kpt_line)):
                m,n = kpt_line[j][0],kpt_line[j][1]
                if kpts[m][0] !=0 and kpts[n][1] !=0:
                    cv2.line(img,(kpts[m][0],kpts[m][1]),(kpts[n][0],kpts[n][1]),colors[j],2)
        self.showNpImg(img)
        


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ImageProcessingApp()
    ex.show() 
    sys.exit(app.exec_())